home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / overview / moreisbetter / mib-libraries / moretextutils / moretextutils.cp next >
Encoding:
Text File  |  2000-06-23  |  5.3 KB  |  251 lines

  1. /*
  2.     File:        MoreTextUtils.cp
  3.  
  4.     Contains:    
  5.  
  6.     Written by:    Pete Gontier
  7.  
  8.     Copyright:    Copyright (c) 1998 Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.  
  20.          <4>     21/4/99    Quinn   Added ValidStringListHandle.
  21.          <3>     2/15/99    PCG     InlineGetHandleSize loses the Inline
  22.          <2>    11/11/98    PCG     fix header
  23.          <1>    11/10/98    PCG     first big re-org at behest of Quinn
  24.  
  25.     Old Change History (most recent first):
  26.  
  27.          <2>    10/23/98    PCG     add GetStringFromLongDouble
  28.          <1>     6/16/98    PCG     initial checkin
  29. */
  30.  
  31. #include "MoreTextUtils.h"
  32.  
  33. #include <Resources.h>
  34. #include <PLStringFuncs.h>
  35.  
  36. pascal OSErr NewStringPtr (ConstStr255Param init, UInt8 maxSize, StringPtr *result)
  37. {
  38.     OSErr err = noErr;
  39.  
  40.     if (!MoreAssert (result && (!init || (*init <= maxSize))))
  41.         err = paramErr;
  42.     else
  43.     {
  44.         *result = StringPtr (NewPtr (1 + (maxSize ? maxSize : (init ? *init : 255))));
  45.  
  46.         if (!*result)
  47.             err = MemError ( );
  48.         else if (init && *init)
  49.             PLstrcpy (*result,init);
  50.         else
  51.             **result = 0;
  52.     }
  53.  
  54.     return err;
  55. }
  56.  
  57. pascal OSErr NewStringListHandle (Handle *h)
  58. {
  59.     DebugStr ("\pThis routine has never been traced.");
  60.  
  61.     if (!MoreAssert (h))
  62.         return nilHandleErr;
  63.     *h = NewHandleClear (sizeof (UInt16));
  64.     if (!*h)
  65.         return MemError ( );
  66.     return noErr;
  67. }
  68.  
  69. pascal OSErr AppendStringToListHandle (ConstStr255Param str, Handle h)
  70. {
  71.     DebugStr ("\pThis routine has never been traced.");
  72.  
  73.     OSErr err = noErr;
  74.  
  75.     if (!MoreAssert (h && *h))
  76.         err = nilHandleErr;
  77.     else
  78.     {
  79.         UInt8 dummyZero;
  80.  
  81.         if (!str)
  82.         {
  83.             dummyZero = 0;
  84.             str = &dummyZero;
  85.         }
  86.  
  87.         if (!(err = PtrAndHand (str, h, *str + 1)))
  88.             (** (UInt16 **) h) += 1;
  89.     }
  90.  
  91.     return err;
  92. }
  93.  
  94. pascal OSErr GetNewStringList (short resID, tStringListP *newStringList)
  95. {
  96.     OSErr err = noErr;
  97.  
  98.     Handle h = GetResource ('STR#',resID);
  99.  
  100.     if (!h)
  101.     {
  102.         err = ResError ( );
  103.         if (!err) err = resNotFound;
  104.     }
  105.     else
  106.     {
  107.         Size handleSize = GetHandleSize (h);
  108.         (void) MoreAssert (MemError ( ) == noErr);
  109.  
  110.         if (handleSize < 2)
  111.             err = paramErr;
  112.         else
  113.         {
  114.             UInt16    stringCount        = ** (UInt16 **) h;
  115.             Size    stringListSize    = sizeof (**newStringList) + (handleSize - 2) +
  116.                                         (stringCount * sizeof (StringPtr));
  117.  
  118.             *newStringList = (tStringListP) NewPtr (stringListSize);
  119.  
  120.             if (!*newStringList)
  121.                 err = MemError ( );
  122.             else
  123.             {
  124.                 (*newStringList)->count = stringCount;
  125.  
  126.                 if (stringCount)
  127.                 {
  128.                     UInt16 index = 0;
  129.  
  130.                     StringPtr stringScan = (StringPtr) ((*newStringList)->list + stringCount);
  131.  
  132.                     BlockMoveData (2 + *h, stringScan, handleSize - 2);
  133.  
  134.                     do
  135.                     {
  136.                         (*newStringList)->list [index] = stringScan;
  137.                         stringScan += *stringScan + 1;
  138.                     }
  139.                     while (++index < stringCount);
  140.                 }
  141.             }
  142.         }
  143.  
  144.         ReleaseResource (h);
  145.         (void) MoreAssert (ResError ( ) == noErr);
  146.     }
  147.  
  148.     return err;
  149. }
  150.  
  151. pascal Boolean ValidStringListHandle(Handle stringList)
  152.     // See comment in interface part.
  153. {
  154.     Boolean result;
  155.     UInt16 stringCount;
  156.     UInt16 stringIndex;
  157.     UInt8* cursor;
  158.     UInt8* bound;
  159.     ByteCount stringListLength;
  160.  
  161.     result = true;
  162.     if (stringList == NULL || *stringList == NULL || GetHandleSize(stringList) < sizeof(UInt16) ) {
  163.         result = false;
  164.     }
  165.     if (result) {
  166.         stringCount = *((UInt16 *) *stringList);
  167.         
  168.         stringListLength = GetHandleSize(stringList);
  169.         
  170.         // From here down we have to make sure we do nothing to move
  171.         // or purge until we're done with cursor and bound.
  172.         
  173.         cursor = ((UInt8 *)*stringList) + sizeof(UInt16);
  174.         bound  = ((UInt8 *)*stringList) + stringListLength;
  175.         for (stringIndex = 0; stringIndex < stringCount; stringIndex++) {
  176.             if ( cursor < bound ) {
  177.                 cursor += *cursor + 1;
  178.             } else {
  179.                 result = false;
  180.                 break;
  181.             }
  182.         }
  183.         
  184.         if (result) {
  185.             if ( cursor != bound ) {
  186.                 result = false;
  187.             }
  188.         }
  189.     }
  190.     
  191.     return result;
  192. }
  193.  
  194. pascal OSErr GetPascalStringFromLongDouble (long double d, SInt8 precision, StringPtr buf)
  195. {
  196.     OSErr err = noErr;
  197.  
  198.     *buf = 0;
  199.  
  200.     //    If client requests more precision than is available, bitch.
  201.  
  202.     if (!MoreAssert (precision < SIGDIGLEN))
  203.         err = paramErr;
  204.     else
  205.     {
  206.         //     If precision is less than 0, client is requesting
  207.         //    as much precision as is available.
  208.  
  209.         if (precision < 0)
  210.             precision = SIGDIGLEN;
  211.  
  212.         //    Try normal notation, and if that overflows,
  213.         //    fall back to scientific notation (bleah!).
  214.  
  215.         decimal dec;
  216.         decform df = { 1, 0, precision };
  217.  
  218.         num2dec (&df,d,&dec);
  219.  
  220.         if (dec.sig.text [0] == '?')
  221.         {
  222.             df.style    = 0;
  223.             df.digits    = SIGDIGLEN;
  224.  
  225.             num2dec (&df,d,&dec);
  226.         }
  227.  
  228.         if (*(dec.sig.text) == '0')
  229.             PLstrcpy (buf,"\p0");
  230.         else if (*(dec.sig.text) == 'I')
  231.             PLstrcpy (buf,"\p[INF]");
  232.         else if (*(dec.sig.text) == 'N')
  233.             PLstrcpy (buf,"\p[NaN]");
  234.         else
  235.         {
  236.             //    Finally, convert it to a pascal string...
  237.  
  238.             dec2str (&df,&dec,(Ptr)buf);
  239.             c2pstr ((Ptr)buf);
  240.  
  241.             //    ...and trim trailing zeroes.
  242.  
  243. //            if (df.style == 1 && dec.exp < 0)
  244. //                while (buf [*buf] == '0')
  245. //                    *buf -= 1;
  246.         }
  247.     }
  248.  
  249.     return err;
  250. }
  251.